package com.example;

import com.mybatisflex.core.datasource.DataSourceKey;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.DbChain;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.MybatisFlexBootstrap;
import com.zaxxer.hikari.HikariDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;

import java.io.InputStream;
import java.util.List;
import java.util.Map;

public class Application {

    // 统一日志
    private static final Logger logger = LoggerFactory.getLogger(Application.class);
    public static void main(String[] args) {

//        logger.error("error信息");
//        logger.warn("warn信息");
//        logger.info("info信息");
//        logger.debug("debug信息");
//        logger.trace("trace信息");

        // 加载YML配置文件
        Yaml yaml = new Yaml();
        InputStream inputStream = Application.class.getResourceAsStream("/application.yml");
        Map<String, Object> config = yaml.load(inputStream);

        // 设置数据源
        HikariDataSource dataSource1 = new HikariDataSource();
        Map<String, Object> ds1Config = (Map<String, Object>) config.get("ds1");
        dataSource1.setJdbcUrl((String) ds1Config.get("url"));
        dataSource1.setUsername((String) ds1Config.get("username"));
        dataSource1.setPassword((String) ds1Config.get("password"));

        HikariDataSource dataSource2 = new HikariDataSource();
        Map<String, Object> ds2Config = (Map<String, Object>) config.get("ds2");
        dataSource2.setJdbcUrl((String) ds2Config.get("url"));
        dataSource2.setUsername((String) ds2Config.get("username"));
        dataSource2.setPassword((String) ds2Config.get("password"));

        MybatisFlexBootstrap.getInstance()
                .setDataSource("ds1", dataSource1)
                .addDataSource("ds2", dataSource2)
                .start();

        // 插入 =====
        // row方式
        Row account = new Row();
        account.set("user_name","Michael");
        Db.insert("tb_account", account);
        // DbChain方式
        DbChain.table("tb_account")
                .set("user_name","zhangsan")
                .save();
        // 纯sql方式
        String sql = "insert into tb_account(  user_name) value ( ?)";
        Db.insertBySql(sql,"michael 3333 ");

        // 更新 =====
        QueryCondition condition = QueryCondition.createEmpty(); // 条件
        condition.and("id < ?", 5); // 这种写法实际上很灵活且安全
        Row row2 = new Row(); // 更新的数据
        row2.set("user_name","Michael 5");
        Db.updateByCondition("tb_account", row2, condition);

        // 删除 =====
        condition = QueryCondition.createEmpty();
        condition.and("user_name = ?", "michael");
        Db.deleteByCondition("tb_account", condition);

        // 查询  =====
        // sql方式
        List<Row> list = Db.selectListBySql("select id,user_name from tb_account where id > ?", 5);
        logger.info(list.toString());
        // Db方式
        Row row = Db.selectOneById("tb_account","id",1);
        logger.info(row.toString());;
        // 基于QueryWrapper
        QueryWrapper query = new QueryWrapper();
        query.select("id","user_name")
                .from("tb_account")
                .where("id > ?" , 5);
        List<Row> result = Db.selectListByQuery("tb_account", query);
        logger.info(result.toString());
        // 基于DbChain
        DbChain.table("tb_account")
                .select("id","user_name","age","birthday")
                .where("age > ?",0)
                .list()
                .forEach(row1 -> {
                    logger.info(row1.toString());
                });

        // 切换数据源（上文默认数据源为ds1)
        try{
            DataSourceKey.use("ds2");
        } catch (Exception e) {
            e.printStackTrace();
        }
        List<Row> rows = Db.selectAll("tb_account_2");
        logger.info(rows.toString());

        // 恢复到默认数据源
        DataSourceKey.clear();

        // 再用默认数据源
        rows = Db.selectAll("tb_account");
        logger.info(rows.toString());

        // ？？？？？？？？？？？？？？？？
        // TODO 有没有办法同时使用多个数据源？
        //  不要来回切换（虽然来回切换的开销并不大）

        // testLogRolling();

    }


    private static void testLogRolling() {
        // 输出 100000 次当前时间，用于测试日志
        for (int i = 0; i < 100000; i++) {
            logger.info(System.currentTimeMillis() + "");
        }
    }


}